package com.msteam.tools.code.controller;

import com.google.gson.Gson;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.druid.DruidPlugin;
import com.msteam.kernel.render.vo.*;
import com.msteam.tools.code.generator.CubeHandGenerator;
import com.msteam.tools.code.model.*;
import com.msteam.tools.code.model.json.*;

import javax.sql.DataSource;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


//@RouterMapping(url = "/code", viewPath = "/WEB-INF/code")
public class CodeController extends Controller {
	private Gson gson = new Gson();
	
	public void index() {
		/*keepPara();
		String action = getPara(0, "index");
		render(String.format("%s.html", action));

		int pageNumber = getParaToInt(1, 1);
		BigInteger userId = getLoginedUser().getId();

		setAttr(UserContentPageTag.TAG_NAME, new UserContentPageTag(action, userId, pageNumber));
		setAttr("action", action);
		setAttr(action, "active");*/
	}
	public void tablepage(){
		
	}
	public void columnpage(){
		setAttr("tableId", this.getPara("tableId"));
	}
	public void refresh(){
		Integer projectId = this.getParaToInt("id");
		CbhProject project = new CbhProject().findById(projectId);
		CubeHandGenerator gen = new CubeHandGenerator(project);
		gen.refreshProjectTableColumns();
		/*//创建表生成器
		JShopExMetaBuilder mmbuilder = new JShopExMetaBuilder(getDataSource(project));
		//添加需要生成的表前缀
		mmbuilder.setTablePrefix(project.getTablePrefix());
		*/
		
		this.renderText(gson.toJson(ResponseJson.SuccessResult()));
	}
	
	/**
	 * 生成代码
	 */
	public void build(){
		Integer projectId = this.getParaToInt("id");
		CbhProject project = new CbhProject().findById(projectId);
		CubeHandGenerator gen = new CubeHandGenerator(project);
		gen.refreshTemplate();
		gen.start();
		
		this.renderText(gson.toJson(ResponseJson.SuccessResult()));
	}
	
	private List<CbhTableJson> wrapCbhTableJson(List<CbhTable> tables){
		List<CbhTableJson> rts = new ArrayList<CbhTableJson>();
		for(CbhTable gt:tables){
			CbhTableJson tj = new CbhTableJson();
			tj.setDISPLAY_NAME(gt.getDisplayName());
			tj.setID(gt.getID());
			tj.setMODEL_NAME(gt.getModelName());
			tj.setPACKAGE_NAME(gt.getPackageName());
			tj.setPRIMARY_KEY(gt.getPrimaryKey());
			tj.setREMARKS(gt.getREMARKS());
			tj.setTABLE_NAME(gt.getTableName());
			//tj.setPREFIX(gt.getPrefix());
			tj.setIS_PROCESS(gt.getIsProcess());
			rts.add(tj);
		}
		return rts;
	}
	private List<CbhColumnJson> wrapCbhColumnJson(List<CbhColumn> columns){
		List<CbhColumnJson> rts = new ArrayList<CbhColumnJson>();
		for(CbhColumn gc:columns){
			CbhColumnJson cj = new CbhColumnJson();
			cj.setATTR_NAME(gc.getAttrName());
			cj.setDEFAULT_VALUE(gc.getDefaultValue());
			cj.setDISPLAY_NAME(gc.getDisplayName());
			cj.setID(gc.getID());
			
			cj.setINPUT_TYPE(gc.getInputType());
			cj.setIN_EDIT(gc.getInEdit());
			cj.setIN_LIST(gc.getInList());
			cj.setIN_VIEW(gc.getInView());
			
			cj.setFRONT_IN_EDIT(gc.getFrontInEdit());
			cj.setFRONT_IN_LIST(gc.getFrontInList());
			cj.setFRONT_IN_VIEW(gc.getFrontInView());
			
			
			cj.setIS_APPLY(gc.getIsApply());
			cj.setIS_NULL_ABLE(gc.getIsNullAble());
			cj.setIS_PRIMARY_KEY(gc.getIsPrimaryKey());
			cj.setJAVA_TYPE(gc.getJavaType());
			cj.setNAME(gc.getNAME());
			cj.setQUERY_BY(gc.getQueryBy());
			cj.setREMARKS(gc.getREMARKS());
			cj.setTABLE_ID(gc.getTableId());
			cj.setTYPE(gc.getTYPE());

			rts.add(cj);
		}
		return rts;
	}
	public void newproject(){
		
		List<PropertyJson> rts = new ArrayList<PropertyJson>();
		rts.add(new PropertyJson("NAME", "项目名称","基本信息","text"));
		rts.add(new PropertyJson("VERSION", "0.0.1","基本信息","text"));
		rts.add(new PropertyJson("AUTHOR", "JADRANKA","基本信息","text"));
		rts.add(new PropertyJson("DESCRIPTION", "项目描述","基本信息","text"));

		String templateId="0";
		EditorJson ej = new EditorJson();
		ej.setType("combobox");
		
		Map<String,Object> options = new HashMap<String, Object>();
		options.put("valueField", "value");
		options.put("textField", "label");
		
		List<LabelValueJson> datas = new ArrayList<LabelValueJson>();
		List<CbhTemplate> gts = new CbhTemplate().find("select * from cbh_template");
		for(CbhTemplate t : gts){
			datas.add(new LabelValueJson(t.getNAME(),t.getID()+""));
			
			templateId = t.getID()+"";
		}

		options.put("data", datas);
		
		ej.setOptions(options);
		
		rts.add(new PropertyJson("TEMPLATE_ID", templateId,"模型处理器",ej));

		rts.add(new PropertyJson("TABLE_PREFIX", "XXX_","数据库","text"));
		rts.add(new PropertyJson("DB_HOST", "127.0.0.1","数据库","text"));
		rts.add(new PropertyJson("DB_NAME", "dbname","数据库","text"));
		rts.add(new PropertyJson("DB_USER", "root","数据库","text"));
		rts.add(new PropertyJson("DB_PASSWORD", "","数据库","text"));

		GridGson gg = new GridGson();
		gg.setTotal(rts.size());
		gg.setRows(rts);
		
		this.renderText(gson.toJson(gg));
	}
	/***  
     * 覆盖原来的内容；  
     *   
     * @param filePath  
     *            文件的路径  
     * @param content  
     *            保存的内容；  
     * @return  
     */  
    private boolean saveFile(String filePath, String content) {  
        boolean successful = true;  
        FileOutputStream fout = null;  
        try {  
            fout = new FileOutputStream(new File(filePath), false);  
            fout.write(content.getBytes());  
        } catch (FileNotFoundException e1) {  
            successful = false;  
        } catch (IOException e) {  
            successful = false;  
        } finally {  
            if (fout != null) {  
                try {  
                    fout.close();  
                } catch (IOException e) {  
                }  
            }  
        }  
        return successful;  
    }  
    
	/**
	 * 更新项目配置
	 */
	public void updateproject(){

		Map t = getRequestObject(HashMap.class);
		CbhProject gt = null;
		if(t.containsKey("ID")){
			gt = new CbhProject().findById(t.get("ID"));
			gt._setAttrs(t);
			gt.update();
		}else{
			gt = new CbhProject();
			gt._setAttrs(t);
			gt.save();
		}
/*		String fileName = "project_"+gt.get("ID")+".txt";

		String fullPath = PathKit.getWebRootPath() +"/WEB-INF/classes/"+fileName;
		StringBuilder sb = new StringBuilder();
		sb.append("db_name="+gt.getDbName()+"\n");
		sb.append("db_host_port=3306\n");
		sb.append("db_tablePrefix=xxx"+"\n");
		sb.append("db_host="+gt.getDbHost()+"\n");
		sb.append("db_password="+gt.getDbPassword()+"\n");
		sb.append("db_user="+gt.getDbUser()+"\n");

		this.saveFile(fullPath, sb.toString());
		
		*/
		
		this.renderText(gson.toJson(ResponseJson.SuccessResult()));
	}
	public void viewproject(){
		
		Integer id = this.getParaToInt("id");
		CbhProject gt = new CbhProject().findById(id);
		
		List<PropertyJson> rts = new ArrayList<PropertyJson>();
		
		rts.add(new PropertyJson("ID", gt.getID(),"基本信息","text"));
		rts.add(new PropertyJson("NAME", gt.getNAME(),"基本信息","text"));
		rts.add(new PropertyJson("VERSION", gt.getVERSION(),"基本信息","text"));
		rts.add(new PropertyJson("AUTHOR", gt.getAUTHOR(),"基本信息","text"));
		rts.add(new PropertyJson("DESCRIPTION", gt.getDESCRIPTION(),"基本信息","text"));
		
		EditorJson ej = new EditorJson();
		ej.setType("combobox");
		
		Map<String,Object> options = new HashMap<String, Object>();
		options.put("valueField", "value");
		options.put("textField", "label");
		
		List<LabelValueJson> datas = new ArrayList<LabelValueJson>();
		List<CbhTemplate> gts = new CbhTemplate().find("select * from cbh_template");
		for(CbhTemplate t : gts){
			datas.add(new LabelValueJson(t.getNAME(),t.getID()+""));
		}

		options.put("data", datas);
		
		ej.setOptions(options);
		
		rts.add(new PropertyJson("TEMPLATE_ID", gt.getTemplateId(),"模型处理器",ej));
		rts.add(new PropertyJson("TABLE_PREFIX", gt.getTablePrefix(),"数据库","text"));
		rts.add(new PropertyJson("DB_HOST", gt.getDbHost(),"数据库","text"));
		rts.add(new PropertyJson("DB_NAME", gt.getDbName(),"数据库","text"));
		rts.add(new PropertyJson("DB_USER", gt.getDbUser(),"数据库","text"));
		rts.add(new PropertyJson("DB_PASSWORD", gt.getDbPassword(),"数据库","text"));

		GridGson gg = new GridGson();
		gg.setTotal(rts.size());
		gg.setRows(rts);
		
		this.renderText(gson.toJson(gg));
	}
	public void projects(){
		List<CbhProjectJson> rts = new ArrayList<CbhProjectJson>();
		CbhProject t = new CbhProject();
		List<CbhProject> datas = t.find("select * from cbh_project");
		for(CbhProject p:datas){
			CbhProjectJson item = new CbhProjectJson();
			item.setID(p.getID());
			item.setNAME(p.getNAME());
			item.setTEMPLATE_ID(p.getTemplateId());
			item.setVERSION(p.getVERSION());
			item.setAUTHOR(p.getAUTHOR());
			item.setDESCRIPTION(p.getDESCRIPTION());
			item.setDB_HOST(p.getDbHost());
			item.setDB_NAME(p.getDbName());
			item.setDB_USER(p.getDbUser());
			item.setDB_PASSWORD(p.getDbPassword());
			rts.add(item);
		}
		
		this.renderText(gson.toJson(rts));
	}
	public void templates(){
		List<CbhTemplateJson> rts = new ArrayList<CbhTemplateJson>();
		CbhTemplate t = new CbhTemplate();
		List<CbhTemplate> datas = t.find("select * from cbh_template");
		for(CbhTemplate p:datas){
			CbhTemplateJson item = new CbhTemplateJson();
			item.setID(p.getID());
			item.setNAME(p.getNAME());

			item.setVERSION(p.getVERSION());
			item.setAUTHOR(p.getAUTHOR());
			
			item.setCODE(p.getCODE());

			rts.add(item);
		}
		GridGson gg = new GridGson();
		gg.setTotal(rts.size());
		gg.setRows(rts);
		this.renderText(gson.toJson(gg));
	}
	
	public void templatefiles(){
		List<TreeJson> rts = new ArrayList<TreeJson>();
		CbhTemplateFile t = new CbhTemplateFile();
		List<CbhTemplateFile> datas = null;
		Integer templateId = this.getParaToInt("templateId");
		String parentId = this.getPara("id");
		if(StrKit.isBlank(parentId)){
			datas = t.find("select * from cbh_template_file where TEMPLATE_ID=? and PARENT_ID is null order by FILE_TYPE asc, NAME asc",templateId);
		}else{
			datas = t.find("select * from cbh_template_file where TEMPLATE_ID=? and PARENT_ID=? order by FILE_TYPE asc, NAME asc",templateId, Integer.parseInt(parentId));
		}
		for(CbhTemplateFile p:datas){
			TreeJson treeNode = new TreeJson();
			CbhTemplateFileJson item = new CbhTemplateFileJson();
			item.setID(p.getID());
			item.setNAME(p.getNAME());
			item.setPARENT_ID(p.getParentId());
			item.setFILE_TYPE(p.getFileType());
			item.setFILE_SIZE(p.getFileSize());
			item.setPROCESS_TYPE(p.getProcessType());
			item.setTEMPLATE_ID(p.getTemplateId());
			item.setPATH(p.getPATH());
			item.setOUTPUT_PATH(p.getOutputPath());
			
			treeNode.setData(item);
			treeNode.setId(p.getID());
			treeNode.setText(p.getNAME());
			//treeNode.setChildren(children);
			if(hasChildrenFiles(templateId, p.getID())){
				treeNode.setState("closed");
			}else{
				//treeNode.setState("closed");
			}
			
			rts.add(treeNode);
		}

		this.renderText(gson.toJson(rts));
	}
	private Boolean hasChildrenFiles(Integer templateId, Integer parentId){
		List<CbhTemplateFile> datas = null;
		CbhTemplateFile t = new CbhTemplateFile();
		datas = t.find("select * from cbh_template_file where TEMPLATE_ID=? and PARENT_ID=?",templateId, parentId);
		if(datas==null || datas.size()==0){
			return false;
		}
		return true;
	}
	public void viewtemplatefile(){
		
		Integer id = this.getParaToInt("id");
		CbhTemplateFile gt = new CbhTemplateFile().findById(id);
		
		List<PropertyJson> rts = new ArrayList<PropertyJson>();
		
		rts.add(new PropertyJson("ID",gt.getID(),"基本信息","hidden"));
		
		EditorJson ej = new EditorJson();
		ej.setType("combobox");
		
		Map<String,Object> options = new HashMap<String, Object>();
		options.put("valueField", "value");
		options.put("textField", "label");
		
		List<LabelValueJson> datas = new ArrayList<LabelValueJson>();
		
		datas.add(new LabelValueJson("静态复制","static"));
		
		datas.add(new LabelValueJson("项目解析","once"));
		datas.add(new LabelValueJson("表级解析","each"));
		datas.add(new LabelValueJson("解压缩","unzip"));
		options.put("data", datas);
		
		ej.setOptions(options);
		
		rts.add(new PropertyJson("PROCESS_TYPE", gt.getProcessType(),"基本信息",ej));
		rts.add(new PropertyJson("OUTPUT_PATH", gt.getOutputPath(),"基本信息","text"));
		rts.add(new PropertyJson("FILE_SIZE", "444","基本信息","label"));
		rts.add(new PropertyJson("DESCRIPTION", gt.getDESCRIPTION(),"描述","textarea"));

		GridGson gg = new GridGson();
		gg.setTotal(rts.size());
		gg.setRows(rts);
		
		this.renderText(gson.toJson(gg));
	}
	public void updatetemplatefile(){

		Map t = getRequestObject(HashMap.class);
		CbhTemplateFile gt = new CbhTemplateFile().findById(t.get("ID"));
		gt.setProcessType((String)t.get("PROCESS_TYPE"));
		gt.setOutputPath((String)t.get("OUTPUT_PATH"));
		gt.setDESCRIPTION((String)t.get("DESCRIPTION"));
		gt.update();
		
		this.renderText(gson.toJson(ResponseJson.SuccessResult()));
	}
	public void tables(){
		GridGson gg = new GridGson();
		CbhTable t = new CbhTable();
		List<CbhTable> gts = t.find("select * from cbh_table where PROJECT_ID=?",this.getParaToInt("id"));
		gg.setTotal(gts.size());
		gg.setRows(wrapCbhTableJson(gts));
		String datas = gson.toJson(gg);
		datas = datas.replaceAll("\":true", "\":\"true\"").replaceAll("\":false", "\":\"false\"");
		this.renderText(datas);
	}
	public void columns(){
		GridGson gg = new GridGson();
		CbhColumn t = new CbhColumn();
		List<CbhColumn> gts = t.find("select * from cbh_column where TABLE_ID="+this.getParaToInt("tableId"));
		gg.setTotal(gts.size());
		gg.setRows(wrapCbhColumnJson(gts));
		String datas = gson.toJson(gg);
		datas = datas.replaceAll("\":true", "\":\"true\"").replaceAll("\":false", "\":\"false\"");
		this.renderText(datas);
	}
	public void updatetable(){
		Map t = getRequestObject(HashMap.class);
		CbhTable gt = new CbhTable().findById(t.get("ID"));
		gt._setAttrs(t);
		gt.update();
		this.renderText(gson.toJson(ResponseJson.SuccessResult()));
	}
	
	public void updatecolumn(){

		Map t = getRequestObject(HashMap.class);
		CbhColumn gt = new CbhColumn().findById(t.get("ID"));
		gt._setAttrs(t);
		gt.update();
		this.renderText(gson.toJson(ResponseJson.SuccessResult()));
	}
	
	public DataSource getDataSource(CbhProject project) {

		String dbHost = project.getDbHost();
		String dbName = project.getDbName();
		String dbUser = project.getDbUser();
		String dbPassword = project.getDbPassword();
		
		String jdbc_url = "jdbc:mysql://" + dbHost + "/" + dbName;
		
		DruidPlugin druidPlugin = new DruidPlugin(jdbc_url, dbUser,dbPassword);
		druidPlugin.start();
		return druidPlugin.getDataSource();
	}
	/**
	 * 取Request中的数据对象
	 * @param valueType
	 * @return
	 * @throws Exception 
	 */
	protected <T> T getRequestObject(Class<T> valueType){
		try{
			StringBuilder json = new StringBuilder();
			BufferedReader reader = this.getRequest().getReader();
			String line = null;
			while((line = reader.readLine()) != null){
				json.append(line);
			}
			String jsonString = json.toString();
			reader.close();
			if(StrKit.isBlank(jsonString)){
				//sendResponseError("参数提交格式错误");
				return null;
			}
			Gson gson = new Gson();
			return gson.fromJson(jsonString, valueType);
		}catch(Exception ex){
			//sendResponseError("参数提交格式错误");
			return null;
		}
	}
}